﻿using System;
using System.Xml;
using System.IO;
using System.Collections.Generic;
using System.Reflection;

namespace Draco.OWF.RT.Engine.Manager
{
    public class ActivityPluginAgent
    {
        protected Manifest m_manifest;
        private String ManifestFilePath;
        private String m_baseURL;

        IDictionary<String, Type> m_ActivityTypes = new Dictionary<String, Type>();
        IDictionary<String, ActivityManifest> m_ActivityManifest = new Dictionary<String, ActivityManifest>();
        Assembly m_pluginAssembly = null;

        public ActivityPluginAgent(String manifestFile)
        {
            if (!System.IO.File.Exists(manifestFile))
            {
                throw new ArgumentException("manifestFile not exist:"+ manifestFile);
            }
            this.m_baseURL = Path.GetDirectoryName(manifestFile);
            this.ManifestFilePath = manifestFile;
            System.Xml.XmlDocument xDoc = new XmlDocument();
            FileStream fileStream = new FileStream(ManifestFilePath,FileMode.Open);
            xDoc.Load(fileStream);

            m_manifest = new Manifest();
            m_manifest.Load(xDoc);

            foreach(ActivityManifest am in m_manifest.ActivityManifests)
            {
                m_ActivityManifest.Add(am.Name, am);
            }
        }

        public String PluginName
        {
            get { return m_manifest.PluginName; }
        }

        public List<ActivityManifest> getActivityManifest()
        {
            return m_manifest.ActivityManifests;
        }

        public Type GetActivityType(String activityName)
        {
            if (!String.IsNullOrWhiteSpace(activityName))
            {
                if (m_ActivityTypes.ContainsKey(activityName))
                {
                    //exist
                    return m_ActivityTypes[activityName];
                }
                //load type
                Type type = LoadActivityType(activityName);
                m_ActivityTypes.Add(activityName,type);
                return type;
            }
            return null;
        }

        public Type LoadActivityType(String activityName)
        {
            try
            {
                if (this.m_pluginAssembly == null)
                {
                    String assemblyName = m_manifest.AssemblyName;
                    Assembly assembly = AssemblyLoader.LoadAssembly(this.AssemblyPath, assemblyName);
                    this.m_pluginAssembly = assembly;
                }
                ActivityManifest manifest = this.m_ActivityManifest[activityName];
                String className = manifest.ClassName;
                Type type = this.m_pluginAssembly.GetType(className);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return null;
        }

        public String AssemblyPath
        {
            get { return Path.Combine(this.m_baseURL, "bin"); }
        }

    }
}
